import * as fs from "fs";
import { Document, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign, AlignmentType } from 'docx';
import { SimulateController } from "./Controller";
import { PinData } from "./types/Docx";
import { SimFrameToSubChannel, SubWinName } from "./types/Win";
import { loading } from "@/common/Loading";

export default class DocxService {

  controller: SimulateController;

  constructor(controller: SimulateController) {
    this.controller = controller as SimulateController;
  }

  transToTableData(
    heads:{key: string, label: string}[],
    data: {[props:string]: string | number | boolean}[],
    opions: { title: string, headOption: { height: number } }) {
    const tableRows = [];
    const headRow = [];

    // table head
    for (const cell of heads) {
      headRow.push(new TableCell({
        verticalAlign: VerticalAlign.CENTER,
        children: [new Paragraph({
          text: cell.label,
          alignment: AlignmentType.CENTER,
        })],
      }));
    }
    tableRows.push(new TableRow({
      children: headRow
    }));

    // table body
    for (const cell of data) {
      const row = [];
      for (let item of heads) {
        row.push(new TableCell({
          children: [new Paragraph(String(cell[item.key] || ''))]
        }));
      }
      tableRows.push(new TableRow({
        children: row
      }));
    }

    // table
    const table = new Table({
      rows: tableRows,
    });

    // doc
    return new Document({
      sections: [{
        children: [
          new Paragraph({ text: opions.title }),
          table,
        ],
      }]
    });
  }

  saveDocument(path: string, doc: Document, cb: () => void) {
    Packer
      .toBuffer(doc)
      .then((buffer: Buffer) => {
        fs.writeFileSync(path, buffer);
      })
      .finally(() => {
        cb();
      });
  }

  transferDataToPinExportWin(data: any) {
    const info = new PinData(data);
    this.controller.winService.sendInfoToSubWins(
      {
        type: SimFrameToSubChannel.ActChangeExportInfo,
        data: info,
      },
      SubWinName.ExportActPinData
    );
  }

  docxSaveTableToWord(path: string, datas: {[props:string]: string | number | boolean}[]) {
    loading.popup(this.controller.locale.localeTrans('_exporting'));
    setTimeout(() => {
      loading.close();
    }, 1000);
    const PinDataToWordHeads = [
      { key: 'id', label: this.controller.locale.localeTrans('_num') },
      { key: 'action', label: this.controller.locale.localeTrans('_f_action') },
      { key: 'behavior', label: this.controller.locale.localeTrans('_b_name') },
      { key: 'owner', label: this.controller.locale.localeTrans('_owner') },
      { key: 'outname', label: this.controller.locale.localeTrans('_o_name') },
      { key: 'outtype', label: this.controller.locale.localeTrans('_o_t') },
      { key: 'outcon', label: this.controller.locale.localeTrans('_o_c') },
      { key: 'action2', label: this.controller.locale.localeTrans('_s_action') },
      { key: 'behavior2', label: this.controller.locale.localeTrans('_b_name') },
      { key: 'inname', label: this.controller.locale.localeTrans('_i_name') },
      { key: 'intype', label: this.controller.locale.localeTrans('_i_t') },
      { key: 'incom', label: this.controller.locale.localeTrans('_i_c') },
    ];
    const title = this.controller.locale.localeTrans('_act_o_record');
    const document = this.transToTableData(PinDataToWordHeads, datas, { title, headOption: { height: 500 } });
    this.saveDocument(path, document, () => {
      console.log('export finally!');
    });
  }

}
